/*
 * CS_DAILY_REWARD_LIST.cpp
 *
 *  Created on: 2013. 7. 25.
 *      Author: the2
 */


#include "../../Command.h"
#include "../../User.h"
#include "../../NResource/Static.h"
#include "../../NLogic/Reward.h"
#include "../../GameLog.h"


namespace ProjectZ { namespace NCommand {

static void SendAckFail(User * pUser, int ack)
{
	::Network::Packet * pAck = ::Network::GETPACKETPOOL()->SEND_NEW();
	* pAck << static_cast<int16_t>(ack);
	pAck->MakePacket(CMD_SC_DAILY_REWARD_LIST);
	pUser->Send(pAck);
}

/*
//연속 접속 보상 리스트 요청
ZNO_CS_DAILY_REWARD_LIST 0x2900
{

}

//연속 접속 보상 리스트 응답
ZNO_SC_DAILY_REWARD_LIST 0x2901
{
	s16	s16ack;
	u8	u8reward_exists;	//연속 접속 보상여부 (0 : 이미 보상 받음, 1 : 보상 있음, 2 : 보상 없음)
	u8	u8reward_today;		//오늘 보상 받을 누적 날짜
	u8	u8count;			//접속 누적 날짜별 보상항목의 개수
	{
		u8	u8reward_day;	//접속 누적 날짜 (1, 2, 3, 4, 5, 6, 7 등등)
		u8	u8reward_value_type;	//보상 유형 (0 : 하트, 1 : 골드, 2: ZEN, 3 : 아이템)
		u32	u32reward_value;		//보상금(골드,젠) 또는 보상개수(아이템, 하트)
		u16	u16reward_icon;			//화면에 보여줄 아이콘의 인덱스

		///다음은 아이템일 때 필요한 값
		u8	u8class_type;
		u8	u8sheet_type;
		u16	u16tid;
	}
}
*/

void Command::CS_DAILY_REWARD_LIST( User * pUser, ::Network::Packet *pPacket )
{
	PREPARE_PACKET;
	DEBUGLOG("%s GID=%d", __FUNCTION__, pUser->GetUserSeq());

	time_t curTime = time(NULL);
	time_t todayInitTime = NLogic::NFunction::GetDailyInitTime(curTime);
	time_t lastDailyRewardTime = 0;

	// 보상 받은 시간 조회
	if (0 != pUser->GetUserInfo().array_Slot[NLogic::Reward::RewardType::DAILY_ATTENDANCE_REWARD].reg_date)
	{
		lastDailyRewardTime = NLogic::NFunction::GetDailyInitTime(pUser->GetUserInfo().array_Slot[NLogic::Reward::RewardType::DAILY_ATTENDANCE_REWARD].reg_date);
	}

	// flag , date 조회
	NLogic::Reward::Data * data = pUser->GetReward()->GetData(NLogic::Reward::RewardType::DAILY_ATTENDANCE_REWARD);

	auto * dailyRewardResource = NResource::Static::Instance().GetDailyReward();
	// 초기화 initMaxFlag
	int initMaxFlag = dailyRewardResource->GetMaxFlag(pUser->GetCompany(), pUser->GetSaleCode());

	// 진행중인 flag 에서 출석 종료일 조회
	int maxDate = dailyRewardResource->GetMaxDate(pUser->GetCompany(), pUser->GetSaleCode(), data->_value);

	TESTLOG("%s todayInitTime %d - lastDailyRewardTime %d = %d", __FUNCTION__, todayInitTime, lastDailyRewardTime, todayInitTime - lastDailyRewardTime);

	uint8_t isReward = 0;
	if (true == ::ProjectZ::Config::Instance().GetResourceDatabase()._isTest)
	{
//		int rankCycle = ::ProjectZ::Config::Instance().GetResourceFile()._rankCycle;
		int rankCycle = 600;

		// Test 연속 로그인 초기화
		if (0 == lastDailyRewardTime || (0 != lastDailyRewardTime && rankCycle < todayInitTime - lastDailyRewardTime))
		{
			TESTLOG("%s 처음 로그인 했거나 하루가 지나서 1일로 초기화", __FUNCTION__);
			data->_value = initMaxFlag;
			data->_subValue = 1;
			isReward = 1;
		}
		else if (rankCycle == todayInitTime - lastDailyRewardTime)
		{
			if (maxDate == data->_subValue)
			{
				TESTLOG("%s 출석 완료로 1일로 초기화", __FUNCTION__);
				data->_value = initMaxFlag;
				data->_subValue = 1;
			}
			else
			{
				data->_subValue++;
				TESTLOG("%s 다음날 출석함. 접속일++ %d일째 접속", __FUNCTION__, data->_subValue);
			}
			isReward = 1;
		}
		else
			isReward = 0; // 보상 없음
	}
	else
	{
		// 연속 로그인 초기화
		if (0 == lastDailyRewardTime || (0 != lastDailyRewardTime && 86400 < todayInitTime - lastDailyRewardTime))
		{
			data->_value = initMaxFlag;
			data->_subValue = 1;
			isReward = 1;
		}
		else if (86400 == todayInitTime - lastDailyRewardTime)
		{
			if (maxDate == data->_subValue)
			{
				data->_value = initMaxFlag;
				data->_subValue = 1;
			}
			else
				data->_subValue++;
			isReward = 1;
		}
		else
			isReward = 0;
	}

	// 연속 접속 보상 flag 와 일자 조회
	NResource::DailyRewardData::Key clsKey(data->_value, data->_subValue);
	NResource::DailyRewardData::Flyweight * pFly = dailyRewardResource->GetFly(pUser->GetCompany(), pUser->GetSaleCode(), clsKey);

	// 보상이 하트일 경우 소식으로 발송..
	if (1 == isReward && 0 == pFly->_REWARD_TYPE)
	{
		int send_heart_count = pFly->_VALUE;

		::Database::Command::Auto clsAuto(::Database::GETCOMMANDPOOL());
		clsAuto->SetQueryType(::Database::Command::INSERT);
		clsAuto->MakeQuery("call sp_insert_data_news(%d, %d, %d, %d, '%s', '%s')", 0, pUser->GetUserSeq(), 4, send_heart_count, "GAMEVIL", "");

		TESTLOG("%s query:[%s]", __FUNCTION__, clsAuto->GetQueryString());

		if (false == ::Database::GETSESSION()->SyncExecute(pUser->GetUserInfo().shard_Item_db_type, clsAuto))
		{
			SendAckFail(pUser, ACK_DB_ERROR);
			return;
		}

		if( clsAuto->GetErrorIdx() != 0 )
		{
			SendAckFail(pUser, ACK_DB_ERROR);
			return ;
		}

		pUser->GetUserInfo().array_Slot[NLogic::Reward::RewardType::DAILY_ATTENDANCE_REWARD].reg_date = curTime;
		pUser->FlushUserInfoCache();
	}
	else if (1 == isReward && 0 != pFly->_REWARD_TYPE) // 보상이 하트가 아닐 경우 메일로 발송..
	{
		// 보상 메일 발송
		NLogic::MailBox::Mail::Data clsMailData;
		clsMailData.send_user_seq		= 0;
		clsMailData.send_user_nickname	= "GAMEVIL";
		clsMailData.recv_user_seq		= pUser->GetUserSeq();
		clsMailData.message				= NResource::Static::InstancePtr()->GetMailMessageResource()->GetMessageDailyReward();

		switch(pFly->_REWARD_TYPE)
		{
		case 1 : // 골드
			clsMailData.gift_status		= EM_GIFT_GOLD;
			clsMailData.gold			= pFly->_VALUE;

			if (false == NLogic::NFunction::SendMail(pUser, clsMailData))
			{
				DEBUGLOG("%s : GOLD Mail Send Fail!!", __FUNCTION__);
				SendAckFail(pUser, ACK_UNKNOWN_ERROR);
				return;
			}
//			NGameLog::LogGoldInfo(pUser, BUY_GOLD_ZEN, pFly->_VALUE);
			break;
		case 2 : // ZEN
			clsMailData.gift_status		= EM_GIFT_ZEN;
			clsMailData.zen				= pFly->_VALUE;
			clsMailData.gift_vcindex	= EM_VCINDEX_DAILY_ATTENDANCE_REWARD;

			if (false == NLogic::NFunction::SendMail(pUser, clsMailData))
			{
				DEBUGLOG("%s : ZEN Mail Send Fail!!", __FUNCTION__);
				SendAckFail(pUser, ACK_UNKNOWN_ERROR);
				return;
			}
			break;
		case 3 : // ITEM
			// 아이템 기본 정보 설정
			clsMailData.item.tid		= pFly->_REWARD_TID;
			clsMailData.item.sub_type	= pFly->_SHEET_TYPE;
			clsMailData.item.class_type	= -1;
			NResource::Static::InstancePtr()->GetItemResource()->setItemEffect(clsMailData.item);

			int sendMailCount	= 0;

			// 스택 아이템인 경우
			if (1 == NResource::Static::InstancePtr()->GetItemResource()->getItemStackType(clsMailData.item))
			{
				clsMailData.item.quantity	= pFly->_VALUE;
				sendMailCount				= 1;
			}
			else
			{
				// 스택 아이템이 아닌 경우 하나씩 첨부하여 발송
				clsMailData.item.quantity	= 1;
				sendMailCount				= pFly->_VALUE;
			}

			// 아이템 부가 정보 세팅
			if (false == NResource::Static::InstancePtr()->GetItemResource()->SetItemDataFromResource(pUser, clsMailData.item))
			{
				DEBUGLOG("%s : SetItemDataFromResource Fail!", __FUNCTION__);
				SendAckFail(pUser, ACK_UNKNOWN_ERROR);
				return;
			}

			clsMailData.gift_status	= EM_GIFT_ITEM;

			// 메일 발송
			for (int i = 0; i < sendMailCount; i++)
			{
				if (false == NLogic::NFunction::SendMail(pUser, clsMailData))
				{
					DEBUGLOG("%s : ITEM Mail Send Fail!!", __FUNCTION__);
					SendAckFail(pUser, ACK_UNKNOWN_ERROR);
					return;
				}
			}
			break;
		}

		pUser->GetUserInfo().array_Slot[NLogic::Reward::RewardType::DAILY_ATTENDANCE_REWARD].reg_date = curTime;
		pUser->FlushUserInfoCache();
	}
	else
	{
		// 보상 없음 isReward == 0
	}

	::Network::Packet * pAck = ::Network::GETPACKETPOOL()->SEND_NEW();

	// 초기화로 flag 변경되었거나 진행중인 flag 에서 출석 종료일 조회
	maxDate = dailyRewardResource->GetMaxDate(pUser->GetCompany(), pUser->GetSaleCode(), data->_value);
	* pAck	<< static_cast<int16_t>(ACK_OK)
			<< isReward
			<< static_cast<uint8_t>(data->_subValue)	// 오늘 보상 받을 누적 날짜
			<< static_cast<uint8_t>(maxDate);	// 접속 누적 날짜별 보상항목의 개수

	TESTLOG("%s isReward %d, date %d, maxDate %d", __FUNCTION__, isReward, data->_subValue, maxDate);

	for (int i = 1; i <= maxDate; i++)
	{
		NResource::DailyRewardData::Key clsKey(data->_value, i);
		NResource::DailyRewardData::Flyweight * pFly = dailyRewardResource->GetFly(pUser->GetCompany(), pUser->GetSaleCode(), clsKey);

		* pAck	<< static_cast<uint8_t>(i)
				<< static_cast<uint8_t>(pFly->_REWARD_TYPE)
				<< static_cast<uint32_t>(pFly->_VALUE)
				<< static_cast<uint16_t>(pFly->_ICON_INDEX)
				<< static_cast<uint8_t>(-1)
				<< static_cast<uint8_t>(pFly->_SHEET_TYPE)
				<< static_cast<uint16_t>(pFly->_REWARD_TID);

		TESTLOG("%s date %d, REWARD_TYPE %d, VALUE %d, ICON_INDEX %d, SHEET_TYPE %d, REWARD_TID %d",
				__FUNCTION__, i, pFly->_REWARD_TYPE, pFly->_VALUE, pFly->_ICON_INDEX, pFly->_SHEET_TYPE, pFly->_REWARD_TID);
	}

	pAck->MakePacket(CMD_SC_DAILY_REWARD_LIST);

	pUser->Send(pAck);
}


} /*NCommand*/ } /*ProjectZ*/


